#define __FAVOR_BSD

//#include <netinet/tcp.h>

#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/ip_icmp.h>
#include <syslog.h>
#include "sn_defines.h"
#include "addrtoname.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define IFSZ 16
#define FLTRSZ 120
#define MAXHOSTSZ 256
#define PCAP_SAVEFILE "./pcap_savefile"


#include <map>
#include <vector>
#include <algorithm>



using namespace std;


//#include "ngrep.h"

int numparam;
int anterior;
long packets=0;
long contador;
int link_offset;
int limitlen = 65535;
char ipD[16];
char ipP[16];
int cont1;
int cont2;

map<int,int> tipos_map;
map<int,string> tipos_map2;
int aux_tipos=0;

ofstream ips("ips.dat",ios::out);
ofstream data("data.dat",ios::out);
ofstream tip("tipos.dat",ios::out);

typedef u_int32_t tcp_seq;
/*
 * TCP header.
 * Per RFC 793, September, 1981.
 */
struct tcphdr
  {
    u_int16_t th_sport;         /* source port */
    u_int16_t th_dport;         /* destination port */
    tcp_seq th_seq;             /* sequence number */
    tcp_seq th_ack;             /* acknowledgement number */
#  if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int8_t th_x2:4;           /* (unused) */
    u_int8_t th_off:4;          /* data offset */
#  endif
#  if __BYTE_ORDER == __BIG_ENDIAN
    u_int8_t th_off:4;          /* data offset */
    u_int8_t th_x2:4;           /* (unused) */
#  endif
    u_int8_t th_flags;
#  define TH_FIN        0x01
#  define TH_SYN        0x02
#  define TH_RST        0x04
#  define TH_PUSH       0x08
#  define TH_ACK        0x10
#  define TH_URG        0x20
    u_int16_t th_win;           /* window */
    u_int16_t th_sum;           /* checksum */
    u_int16_t th_urp;           /* urgent pointer */
};



struct udphdr
{
  u_int16_t uh_sport;           /* source port */
  u_int16_t uh_dport;           /* destination port */
  u_int16_t uh_ulen;            /* udp length */
  u_int16_t uh_sum;             /* udp checksum */
};





struct sniff_udp {
         u_int16_t uh_sport;           /* source port */
         u_int16_t uh_dport;           /* destination port */
         u_int16_t uh_ulen;            /* udp length */
         u_int16_t uh_sum;             /* udp checksum */
};
struct sniff_ethernet {

        u_char  ether_dhost[ETHER_ADDR_LEN];    /* Destination host address */
        u_char  ether_shost[ETHER_ADDR_LEN];    /* Source host address */
        u_short ether_type;                     /* IP? ARP? RARP? etc */

};
struct paquete{

	int p_origen;		//Puerto Origen
	int p_destino;		//Puerto Destino
	int protocolo;		//Protocolo 0 si es TCP 1 UDP 2 ICMP
	int tiempo_vida;	//Tiempo de vida del paquete
	int tipo_servicio;	// Tipo de servicio
	int largo;		//Largo de paquete IP
	int largo_cabecera_udp; //Longitud de cabecera UDP
	int largo_cabecera_tcp; //Longitud de cabecera TCP
	int numero_opciones_tcp;
	int largo_opciones_udp;
	int tipo_ICMP;
	int codigo_mensaje_ICMP;
	int bit_reservado_RB;
	int mas_fragmentos; 	//0 si 1 no
	int opciones_IP;	//Numero de opciones del paquete IP
	int bit_reservado_F1;
	int bit_reservado_F2;
	int flag_urg;
	int flag_ack;
	int flag_push;
	int flag_reset;
	int flag_syn;
	int flag_fin;
	int flag_ece;
	int flag_cwr;
	int tamano_ventana; //Tamao ventana deslizante
	char IPorigen[20];
	char IPdestino[20];
        float porcentaje;

};
/* IP header */

/* TCP header */
struct sniff_tcp {
        u_short th_sport;                       /* Puerto de origen */
        u_short th_dport;                       /* Puerto de destino */
        tcp_seq th_seq;                         /* Nmero de sequencia */
        tcp_seq th_ack;                         /* Nmero de reconocimiento */
        #if BYTE_ORDER == LITTLE_ENDIAN
                u_int   th_x2:4,                /* no usado */
                        th_off:4;               /* data offset */
        #endif
        #if BYTE_ORDER == BIG_ENDIAN
                u_int   th_off:4,               /* data offset */
                        th_x2:4;                /* no usuado */
        #endif
        u_char  th_flags;
        #define TH_FIN  0x01
        #define TH_SYN  0x02
        #define TH_RST  0x04
        #define TH_PUSH 0x08
        #define TH_ACK  0x10
        #define TH_URG  0x20
        #define TH_ECE  0x40
        #define TH_CWR  0x80
        #define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
        u_short th_win;                         /* ventana */
        u_short th_sum;                         /* checksum */
        u_short th_urp;                         /* urgent pointer */
};

void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);

void guardar_paquete(int protos, int origen, int destino, int t_vida, int t_tos, int t_len,
			int t_largo_cabe, int t_ventana, int ack, int syn, int rst, int fin, int urg,
			int push, int ece, int cwr, int frg, int cod_ICMP, int tipo_ICMP, float porcentaje,
			char IPorigen[20], char IPdestino[20]);




//void analizar_paquete();
float calculoPorcentaje(int vector[256], int cantidad);

/********* M�odo que guarda el paquete de datos capturado en una
estructura de datos *******************************/

void guardar_paquete(int protos, int origen, int destino, int t_vida, int t_tos, int t_len, int t_largo_cabe,
			int t_ventana, int ack, int syn, int rst, int fin, int urg, int push, int ece,
			int cwr, int frg, int cod_ICMP, int tipo_ICMP, float porcentaje, char IPorigen[20],
			char IPdestino[20])
{

//cout << "wazup!" << endl;
//cout << protos << "..." << origen << endl;	
	struct paquete pk;

	pk.p_origen = origen;
	pk.p_destino = destino;
	pk.protocolo = protos;			//Protocolo 0 si es TCP 1 UDP 2 ICMP
	pk.tiempo_vida = t_vida;		//Tiempo de vida del paquete
	pk.tipo_servicio = t_tos;		// Tipo de servicio
	pk.largo = t_len;			//Largo de paquete IP
	pk.largo_cabecera_tcp = t_largo_cabe;	//Longitud de cabecera TCP
	pk.tamano_ventana = t_ventana;
	pk.flag_urg = urg;
	pk.flag_ack = ack;
	pk.flag_push = push;
	pk.flag_reset = rst;
	pk.flag_syn = syn;
	pk.flag_fin = fin;
	pk.flag_ece = ece;
	pk.flag_cwr = cwr;
	pk.mas_fragmentos = frg;
	pk.codigo_mensaje_ICMP = cod_ICMP;
	pk.tipo_ICMP = tipo_ICMP;
	strcpy(pk.IPorigen,IPorigen);
	strcpy(pk.IPdestino,IPdestino);
	pk.porcentaje =porcentaje;
	//analizar_paquete(pk);


//cout << origen << "," << destino << "," << protos << "," << t_vida << "," << t_tos << "," <<  t_len << "," << t_largo_cabe << "," << t_ventana << "," << urg << "," << ack << "," << push << "," << rst << "," << syn << "," << fin << "," << ece << "," << cwr << "," << frg << "," << cod_ICMP << "," << tipo_ICMP << "," << porcentaje << endl;
//
if(aux_tipos==1){
   if(tipos_map[packets]==1){

      ips << packets  << ": " << IPorigen << " ---> " << IPdestino << endl;

      data << origen << "," << destino << "," << protos << "," << t_vida << "," << t_tos << "," <<  t_len << "," << t_largo_cabe << "," << t_ventana << "," << urg << "," << ack << "," << push << "," << rst << "," << syn << "," << fin << "," << ece << "," << cwr << "," << frg << "," << cod_ICMP << "," << tipo_ICMP << "," << porcentaje << endl;


      tip << tipos_map2[packets] << endl;


   }
}else{

      data << origen << "," << destino << "," << protos << "," << t_vida << "," << t_tos << "," <<  t_len << "," << t_largo_cabe << "," << t_ventana << "," << urg << "," << ack << "," << push << "," << rst << "," << syn << "," << fin << "," << ece << "," << cwr << "," << frg << "," << cod_ICMP << "," << tipo_ICMP << "," << porcentaje << endl;
}
}

/**************** M�odo que realiza el c�culo del porcentaje del caracter m� repetido **********/

float calculoPorcentaje(int vector[256], int cantidad)
{
 	int i; int temp; float porcentaje;

	temp=vector[0];
	
	if(cantidad==0)
		return 0;

 	for(i=1;i<256;i++)
 	{
 	 	if(vector[i]>temp)
 			temp=vector[i];
 	}

 	porcentaje=(float)temp/(float)cantidad;
 	return porcentaje;
}

/************** M�odo ejecutado al capturar un paquete*****************/

void got_packet(u_char *data1, const struct pcap_pkthdr *h, const u_char *p) {


packets++;
	int largo; int i; int ascii[256];
        struct ip* ip_packet = (struct ip *)(p + link_offset);

//        struct ip* ip_packet = (struct ip *)(p+link_offset);
//cout << "link_offset " << link_offset << endl;


//printf("TTL: %d \n",ip_packet->ip_ttl);
//cout << "u_char *p: " << p << endl;
//cout << "ip_packet->ip_p:" << ip_packet->ip_p << endl;

#if defined(AIX)
#undef ip_hl
	unsigned ip_hl = ip_packet->ip_ff.ip_fhl*4;
#else
	unsigned ip_hl = ip_packet->ip_hl*4;
#endif

	unsigned ip_off = ntohs(ip_packet->ip_off);
 	unsigned fragmented = ip_off & (IP_MF | IP_OFFMASK);
  	unsigned frag_offset = fragmented?(ip_off & IP_OFFMASK) * 8:0;
	//int k;
	char *data;
	int len;
	char tmpIPO[20];
	char tmpIPD[20];
	char dataTMP[200];
	//char dataTCPTMP[1000];
	char direccion[100];
	int j;
	float porcenTCP;
	float porcenUDP;
 	int ack, syn, rst, fin, urg, push, ece, cwr, frg, cod_icmp, tipo_icmp;

    ack=0;syn=0;rst=0;fin=0;urg=0;push=0;ece=0;cwr=0;frg=0, cod_icmp=0,tipo_icmp=0,porcenTCP=0,
	porcenUDP=0;





   	for(j=0;j<256;j++)
   		ascii[j] = 0;




    //si el paquete es de tipo TCP   	
//cout << link_offset << endl;
cout <<"	ip_packet->ip_p==IPPROTO_TCP" << ip_packet->ip_p << " :::: " << IPPROTO_TCP << endl;
cout <<" packet: " << packets << endl;
	if (ip_packet->ip_p==IPPROTO_TCP) {
cout << "Entro a TCP... packet:" << packets << endl;
		struct tcphdr* tcp = (struct tcphdr *)(((char *)ip_packet) + ip_hl);
		unsigned tcphdr_offset = fragmented?0:(tcp->th_off * 4);
		strcpy(direccion,"ws1_1.diinf.usach.cl");

//cout << __LINE__ << endl;

//cout << __LINE__ << endl;


			data = ((char*)tcp) + tcphdr_offset;
		
			if ((len = ntohs(ip_packet->ip_len)) < h->caplen)
				len -= ip_hl + tcphdr_offset;
			else
				len = h->caplen - link_offset - ip_hl - tcphdr_offset;

                        int aux_largo=strlen(data);
			for(j=0;j<aux_largo;j++)
	    		{
    	    			ascii[data[j]+128]=ascii[data[j]+128]+1;
			    }
       		porcenTCP=calculoPorcentaje(ascii,strlen(data));
			if (tcphdr_offset || !frag_offset) {

				if(tcp->th_flags & TH_ACK)
			   		ack=1;
				else
					ack=0;
                        	
               	if(tcp->th_flags & TH_SYN)
					syn=1;
				else
					syn=0;

               	if(tcp->th_flags & TH_RST)
					rst=1;
				else
					rst=0;

               	if(tcp->th_flags & TH_FIN)
					fin=1;
				else
					fin=0;
			
				if(tcp->th_flags & TH_URG)
					urg=1;
				else
					urg=0;

               	if(tcp->th_flags & TH_PUSH)
					push=1;
				else
					push=0;
			
				if(tcp->th_flags & TH_ECE)
					ece=1;
				else
					ece=0;
			
				if(tcp->th_flags & TH_CWR)
					cwr=1;
				else
					cwr=0;
		
           		if (fragmented)
           				{
                 			frg=1;
                        }
           		else
			 		frg=0;
				
				strcpy(tmpIPO,inet_ntoa(ip_packet->ip_src));
				strcpy(tmpIPD,inet_ntoa(ip_packet->ip_dst));

//cout << __LINE__ << endl;
				//guarda datos de paquete TCP				
				guardar_paquete(0,ntohs(tcp->th_sport), ntohs(tcp->th_dport), ip_packet->ip_ttl,
						ip_packet->ip_tos, ip_packet->ip_len, ip_packet->ip_hl, tcp->th_win,
						ack, syn, rst, fin, urg, push,ece,cwr,frg,0,0,porcenTCP,tmpIPO,
						tmpIPD);
		}
	}

        //si el paquete es de tipo UDP
  	if(ip_packet->ip_p==IPPROTO_UDP)
	{
		struct udphdr* udp = (struct udphdr *)(((char *)ip_packet) + ip_hl);
		unsigned udphdr_offset = (fragmented)?0:sizeof(struct udphdr);

                len=0;
	
	//filtro por IP
	/*if(strcmp(inet_ntoa(ip_packet->ip_src),"135.8.60.182")==0 &&
	   strcmp(inet_ntoa(ip_packet->ip_dst), "172.16.112.50")==0)
		{*/
        	data = ((char*)udp) + udphdr_offset;
		largo=sizeof(&data)/sizeof(char);	    
		strcpy(dataTMP,data);
		
		if ((len = ntohs(ip_packet->ip_len)) < h->caplen)
                	len -= ip_hl + udphdr_offset;
        else
    	        	len = h->caplen - link_offset - ip_hl - udphdr_offset;
  		
		for(i=0;i<len;i++)
		{
			if((i%16)==0)
			ascii[dataTMP[i]+128]=ascii[dataTMP[i]+128]+1;
		}
		porcenUDP=calculoPorcentaje(ascii,len);

		if (fragmented)
			frg=1;
        else
			frg=0;
        if (udphdr_offset || !frag_offset) {

//cout << __LINE__ << endl;
#ifdef HAVE_DUMB_UDPHDR
    		//guarda datos de paquete UDP
    		guardar_paquete(1,ntohs(udp->source), ntohs(udp->dest), ip_packet->ip_ttl, ip_packet->ip_tos,
    				ip_packet->ip_len, ip_packet->ip_hl, 0,ack, syn, rst, fin, urg, push,ece,cwr,
    				frg,0,0,porcenUDP,tmpIPO,tmpIPD);

#else
		strcpy(tmpIPO,inet_ntoa(ip_packet->ip_src));
		strcpy(tmpIPD,inet_ntoa(ip_packet->ip_dst));
		//guarda datos de paquete UDP

//cout << __LINE__ << endl;
		guardar_paquete(1,ntohs(udp->uh_sport), ntohs(udp->uh_dport), ip_packet->ip_ttl, ip_packet->ip_tos,
				ip_packet->ip_len, ip_packet->ip_hl, 0,ack, syn, rst, fin, urg, push,ece,cwr,frg,0,0,
				porcenUDP,tmpIPO, tmpIPD);

#endif
            }  //fin filtro por IP
        }
	
//cout << __LINE__ << endl;
	
	if(ip_packet->ip_p==IPPROTO_ICMP)
	{
		struct icmp* ic = (struct icmp *)(((char *)ip_packet) + ip_hl);
		unsigned icmphdr_offset = fragmented?0:4;
                 strcpy(tmpIPO,inet_ntoa(ip_packet->ip_src));
				strcpy(tmpIPD,inet_ntoa(ip_packet->ip_dst));
		data = ((char*)ic) + icmphdr_offset;
		if ((len = ntohs(ip_packet->ip_len)) < h->caplen)
			len -= ip_hl + icmphdr_offset;
		else
			len = h->caplen - link_offset - ip_hl - icmphdr_offset;

            	if (len > limitlen)
            		len = limitlen;

                if (icmphdr_offset || !frag_offset)
                   	{
                   		cod_icmp = ic->icmp_code;
                   		tipo_icmp = ic->icmp_type;
                   	}

                if (fragmented)
                   frg=1;
                else 
                   frg=0;



	        char aux[10];
		sprintf(aux,"0");


//cout << __LINE__ << endl;
		//guarda datos de paquete ICMP
		guardar_paquete(2,0,0,ip_packet->ip_ttl, ip_packet->ip_tos, ip_packet->ip_len, ip_packet->ip_hl,
				0,ack, syn, rst, fin, urg, push,ece,cwr,frg,cod_icmp,tipo_icmp,0,aux,aux);

        }

//cout << __LINE__ << endl;
}
//fin got_packet

//modo de empleo

int usage(char *progname){

   printf("Uso: %s -i <interfaz> [-f <archivo entrada> -l <cantidad de paquetes>]\n",progname);
   exit(7);

}

//void got_packet(u_char *data1, const struct pcap_pkthdr *h, const u_char *p) {
void print_addrs(u_char *user, const struct pcap_pkthdr *hdr, const u_char *data)
{
	int offset = 26; //14 MAC header + 12 IP
	if(hdr->caplen < 30){

		//Los datos capturados no son suficientes para extraer la direccion IP
		fprintf(stderr,"Error: El paquete capturado no es lo suficientemente grande para extraer direcciones IP.\n");
		return;

	}
	printf("Paquete recivido desde: %d. %d. %d. %d.\n", data[offset], data[offset+1], data[offset+2], data[offset+3]);

	if( hdr->caplen >= 34) {

		printf("y destinado a %d. %d. %d. %d \n",data[offset+4],data[offset+5],data[offset+6],data[offset+7]);

	}
	packets++;


}



int split(vector<string>& v, const string& str, char c)
{
v.clear();
string::const_iterator s = str.begin();
while (true) {
  string::const_iterator begin = s;

    while (*s != c && s != str.end()) { ++s; }

        v.push_back(string(begin, s));
        if (s == str.end()) {
            break;
        }
       
       if (++s == str.end()) {
            v.push_back("");
            break;
       }
   }
   return v.size();
}
/**************** Programa Principal **********************************/

int main(int argc, char **argv)
{
	char ifname[IFSZ];	//nombre de la interfaz
        char* dev;                      /* Sniffing device */
        char errbuf[PCAP_ERRBUF_SIZE];  /* Error buffer */
        pcap_t *descr;                  /* Sniff handler */
	char filename[80];	//nombre del savefile a leer
	struct bpf_program fp;          /* hold compiled program */
        bpf_u_int32 maskp;              /* subnet mask */
        bpf_u_int32 netp;               /* ip */
        char filter_app[] = "";
        int numpackets = 10000;          /* How many packets to sniff */

 	cont1=0;
	cont2=0;
	numparam=argc;
	int aux_iface=0;
	int aux_archivo=0;
	int aux_numpackets=0;

	int f;
	char prestr[80];
	int majver =0, minver =0; // versiones
	pcap_t *p;

//cout << __LINE__ << endl;

dev=NULL;
	ifstream archivo,tipos;

//cout << __LINE__ << endl;


	for(int i = 0; i < argc; i++){
	
	
	if(!strcmp(argv[i],"-f")){
	    f=i+1;

	    aux_archivo=1;
	    strcpy(filename,argv[f]);
	    archivo.open(argv[f]);

	    if(!archivo){

	      cout << "Fallo al intentar abrir el archivo: " << argv[f] << endl;
	      return -1;

	    }

	}
	if(!strcmp(argv[i],"-t")){
	    f=i+1;

	    aux_tipos=1;
	    tipos.open(argv[f]);

	    if(!tipos){

	      cout << "Fallo al intentar abrir el archivo: " << argv[f] << endl;
	      return -1;

	    }

	}
	if(!strcmp(argv[i],"-i")){
	    f=i+1;
	    aux_iface=1;
	    strcpy(ifname,argv[f]);

	 }
	if(!strcmp(argv[i],"-l")){
	    f=i+1;
	    aux_numpackets=1;
	    numpackets=atoi(argv[f]);

	 }
	if(!strcmp(argv[i],"-h")){
	    usage(argv[0]);

	 }

	}

if(aux_tipos==1){
  string linea;
  vector<string> vec;

//  ofstream tt("test",ios::out);

  

  while (! tipos.eof() )
  {


    getline (tipos,linea);
    split(vec,linea,' ');
    tipos_map[atoi(vec[0].c_str())]=1;

    tipos_map2[atoi(vec[0].c_str())]=vec[11];
//    tt << vec[0] << " " << vec[11] << endl;

  }

}






//cout << __LINE__ << endl;

if(aux_iface!=1){
	cout << "Interface no definida" << endl;
	cout << "Se utilizara la primera compatible" << endl;

	dev = pcap_lookupdev(errbuf);
	pcap_lookupnet(dev, &netp, &maskp, errbuf);
	descr = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
	cout << "Interfaz:  " << dev << endl;

}else{

cout << __LINE__ << endl;
	cout << "Interfaz:  " << ifname << endl;
	pcap_lookupnet(ifname, &netp, &maskp, errbuf);
	descr = pcap_open_live(ifname, BUFSIZ, 1, 0, errbuf);
}

switch(pcap_datalink(descr)) {
		case DLT_EN10MB:
			link_offset = ETHHDR_SIZE;
            	break;

        	case DLT_IEEE802:
			link_offset = TOKENRING_SIZE;
		break;

		case DLT_FDDI:
			link_offset = FDDIHDR_SIZE;
		break;

		case DLT_SLIP:
			link_offset = SLIPHDR_SIZE;
		break;

		case DLT_PPP:
			link_offset = PPPHDR_SIZE;
		break;

		case DLT_RAW:
			link_offset = RAWHDR_SIZE;
		break;

#ifdef HAVE_LOOP
		case DLT_LOOP:
#endif
		case DLT_NULL:
			link_offset = LOOPHDR_SIZE;
		break;

#ifdef HAVE_SLL
		case DLT_LINUX_SLL:
			link_offset = ISDNHDR_SIZE;
		break;
#endif

#ifdef HAVE_802_11
		case DLT_IEEE802_11:
			link_offset = IEEE80211HDR_SIZE;
		break;
#endif

		default:
			fprintf(stderr, "fatal: tipo de interfaz no soportada %d\n", pcap_datalink(descr));
			exit(-1);
	}




if(aux_archivo!=1){
	cout << "Archivo tcpdump no definido" << endl;
	cout << "Se entrara a modo promiscuo" << endl;

//cout << __LINE__ << endl;

        /* Print devise to the user */
        
        printf("Num of packets: [%d]\n", numpackets);
        printf("Filter app: [%s]\n", filter_app);
	//syslog(LOG_INFO,"Inicio de sesion IDS");
	printf("Analizando...\n");
	anterior = 0;


	
        if (descr == NULL)
        {
                printf("pcap_open_live(): %s\n", errbuf);
                exit(1);
        }

        /* Apply the rules */
        if( pcap_compile(descr, &fp, filter_app, 0, netp) == -1)
        {
                printf("pcap_compile borqed\n");
                exit(1);
        }
        if (pcap_setfilter(descr, &fp) == -1)
        {
                printf("pcap_setfilter said 'error'\n");
                exit(1);
        }
	

    for(contador=0;contador<numpackets;contador++){

		pcap_loop(descr, numpackets, got_packet, NULL);
	}
        pcap_close(descr);

        printf("Termino de sniffear\n");
}else{
//Entrando en modo lectura de archivo

//cout << __LINE__ << endl;
//	strcpy(ifname,dev);


	/*Abre la interfaz para la captura de datos.
	* Debe llamarse antes de capturar cualquier paquete
	*/
	if(!(p = pcap_open_offline(filename,errbuf)))
	{

		fprintf(stderr,"Error abriendo el fichero, %s, en modo lectura: %s\n", filename, errbuf);
		exit(2);

	}
	//pcacp_dispach(), por cada paquete lee del savefile hasta error o EOF

	pcap_dispatch(p,0,&got_packet, (u_char *)0);
/*	if(pcap_dispatch(p,0,&got_packet, (u_char *)0) < 0){
//	if(pcap_dispatch(p,0,&print_addrs, (u_char *)0) < 0){
		
		sprintf(prestr,"Error, no puedo leer de la interfaz %s",ifname);
		cout << endl;
		pcap_perror(p,prestr);
		exit(4);
	}
*/
	cout << endl << "Paquetes leidos: " << packets << endl;


	//mostramos las versiones en pantalla

	if(!(majver = pcap_major_version(p))){
	
		fprintf(stderr,"Error obteniendo la -mayor version- de la interfaz: %s", ifname);
		exit(5);

	}

	printf("La -mayor version- usada para crear el fichero es: %d. \n", majver);

	if(!(minver = pcap_minor_version(p)))
	{
		fprintf(stderr,"Error obteniendo la -menor version- de la interfaz: %s", ifname);
		exit(6);
	}

	printf("La -menor version-: %d\n", minver);

	pcap_close(p); //Cerramos el dispositivo de captura y la memoria usada por el descriptor





}



        
        return(0);
}
